package com.agileai.portal.servlet;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.apache.pluto.container.PortletContainer;

import com.agileai.common.AppConfig;
import com.agileai.domain.DataParam;
import com.agileai.domain.DataRow;
import com.agileai.hotweb.common.BeanFactory;
import com.agileai.hotweb.common.Constants;
import com.agileai.hotweb.common.HandlerParser;
import com.agileai.hotweb.controller.core.BaseHandler;
import com.agileai.hotweb.database.OracleClobConverter;
import com.agileai.hotweb.domain.core.Profile;
import com.agileai.hotweb.domain.core.Role;
import com.agileai.hotweb.domain.core.User;
import com.agileai.hotweb.renders.RedirectRenderer;
import com.agileai.hotweb.renders.ViewRenderer;
import com.agileai.hotweb.servlet.DispatchServlet;
import com.agileai.portal.bizmoduler.base.PtHandler;
import com.agileai.portal.bizmoduler.base.PtHandlerManage;
import com.agileai.portal.driver.AttributeKeys;
import com.agileai.portal.driver.service.DriverConfiguration;

public class PortalDispatchServlet extends DispatchServlet {
	private static final long serialVersionUID = 1L;
	
	protected Logger LOG = Logger.getLogger(PortalDispatchServlet.class);
	
	protected void initResource(){
		super.initResource();
		
		ServletContext servletContext = this.getServletContext();
		BeanFactory beanFactory = BeanFactory.instance();
		
		DriverConfiguration driverConfiguration = (DriverConfiguration) beanFactory.getBean("DriverConfiguration");
		servletContext.setAttribute(AttributeKeys.DRIVER_CONFIG, driverConfiguration);
		PortletContainer container = (PortletContainer) beanFactory.getBean("PortletContainer");
		servletContext.setAttribute(AttributeKeys.PORTLET_CONTAINER, container);		
		
		AppConfig appConfig = beanFactory.getAppConfig();
		boolean handleOracleClob = appConfig.getBoolConfig("GlobalConfig", "HandleOracleClob");
		if (handleOracleClob){
			handleOracleClob();
		}
	}

	protected void process(HttpServletRequest request, HttpServletResponse response) throws ServletException,
			IOException {
		log.debug("DispatchServlet------start");
		try {
			ViewRenderer viewRenderer = null;
			String handlerId = parseHandlerId(request);
			ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
			List<String> publicHandlerIdList = PublicHandlerIdListCache.get(classLoader);
			if (isExpired(request) 
					&& !Constants.FrameHandlers.LoginHandlerId.equals(handlerId)
					&& !publicHandlerIdList.contains(handlerId)
					) {
				viewRenderer = new RedirectRenderer(request.getContextPath());
			} else {
				boolean accessValid = false;
				PtHandlerManage ptHandlerManage = (PtHandlerManage)BeanFactory.instance().getBean("ptHandlerManageService");
				PtHandler ptHandler = ptHandlerManage.getHandler(handlerId);
				if (ptHandler != null){
					String accesssType = ptHandler.getAcccessType();
					if (PtHandler.AcccessType.AUTHED.equals(accesssType)){
						if (!isExpired(request)){
							accessValid = true;
						}else{
							accessValid = false;
						}
					}
					else if (PtHandler.AcccessType.MANAGE.equals(accesssType)){
						User user = getUser(request);
						if (user == null){
							accessValid = false;	
						}
						else if (hasAdminRole(user) || user.isAdmin()){
							accessValid = true;
						}else{
							accessValid = false;
						}
					}
					else if (PtHandler.AcccessType.SYSTEM.equals(accesssType)){
						User user = getUser(request);
						if (user == null){
							accessValid = false;	
						}
						else if (user.isAdmin()){
							accessValid = true;
						}else{
							accessValid = false;
						}
					}else{
						accessValid = true;
					}
				}else{
					accessValid = true;
				}
				if (accessValid){
					BaseHandler handler = HandlerParser.getOnly().instantiateHandler(handlerId);
					handler.setDispatchServlet(this);
					handler.setRequest(request);
					handler.setResponse(response);
					DataParam param = new DataParam(request.getParameterMap());
					viewRenderer = handler.processRequest(param);
					viewRenderer.setHandler(handler);
					viewRenderer.executeRender(this, request, response);
				}else{
					BaseHandler handler = HandlerParser.getOnly().instantiateHandler("Error");
					handler.setDispatchServlet(this);
					handler.setRequest(request);
					handler.setResponse(response);
					DataParam param = new DataParam(request.getParameterMap());
					viewRenderer = handler.processRequest(param);
					viewRenderer.setHandler(handler);
					viewRenderer.executeRender(this, request, response);
				}
			}
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		log.debug("DispatchServlet------end");
	}
	private boolean hasAdminRole(User user){
		boolean result = false;
		List<Role> roleList = user.getRoleList();
		for (Role role : roleList) {
			if (role.getRoleCode().equals("admin")){
				result = true;
				break;
			}
		}
		return result;
	}
	protected User getUser(HttpServletRequest request){
		User user = null;
		HttpSession session = request.getSession(false);
		if (session != null){
			Profile profile = (Profile)session.getAttribute(Profile.PROFILE_KEY);
			if (profile != null){
				user = (User)profile.getUser();				
			}
		}
		return user;
	}
	
	protected void handleOracleClob(){
		OracleClobConverter oracleClobConverter = new OracleClobConverter();
		
		DataRow.addGlobalConvert("SCHEDULE_TITLE",oracleClobConverter);
		DataRow.addGlobalConvert("SCHEDULE_CONTENT",oracleClobConverter);
		DataRow.addGlobalConvert("SCHEDULE_COMMENT",oracleClobConverter);
		
		DataRow.addGlobalConvert("RENDER_FUNC",oracleClobConverter);
		
		DataRow.addGlobalConvert("CALLBACK_FUNC",oracleClobConverter);
		DataRow.addGlobalConvert("ONLOAD_CALLBACK",oracleClobConverter);
		DataRow.addGlobalConvert("RENDER_FUNC",oracleClobConverter);
		
		DataRow.addGlobalConvert("MSG_NOTICE_CONTENT",oracleClobConverter);
		DataRow.addGlobalConvert("USER_PERSONAL",oracleClobConverter);
		
		DataRow.addGlobalConvert("PERSONAL_THEMES",oracleClobConverter);
		DataRow.addGlobalConvert("TEMPT_CONTENT",oracleClobConverter);
		
		DataRow.addGlobalConvert("PTLET_PARAMS",oracleClobConverter);
		DataRow.addGlobalConvert("PTLET_DECOR_PARAMS",oracleClobConverter);
		
		DataRow.addGlobalConvert("TEMPT_CONTENT",oracleClobConverter);
		DataRow.addGlobalConvert("DATA_CONTENT",oracleClobConverter);
		DataRow.addGlobalConvert("THEME_DECOR_PARAMS",oracleClobConverter);
		DataRow.addGlobalConvert("USER_FAVORITES",oracleClobConverter);
		DataRow.addGlobalConvert("COMT_TEXT",oracleClobConverter);
		DataRow.addGlobalConvert("REW_CONTENT",oracleClobConverter);
		DataRow.addGlobalConvert("INFO_CONTENT",oracleClobConverter);
		DataRow.addGlobalConvert("INFO_REL_INFOIDS",oracleClobConverter);
	}
}